{
 "cells": [
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-03-15T13:48:20.678246Z",
     "start_time": "2025-03-15T13:48:19.606998Z"
    }
   },
   "source": [
    "import os\n",
    "import requests\n",
    "import base64\n",
    "import time\n",
    "from PIL import Image\n",
    "from io import BytesIO\n",
    "from datetime import datetime"
   ],
   "outputs": [],
   "execution_count": 1
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-15T14:56:15.798512Z",
     "start_time": "2025-03-15T14:56:15.758383Z"
    }
   },
   "cell_type": "code",
   "source": [
    "INPUT_PATH = \"C:/Users/Lenovo/Desktop/DC/output_frames\"         # 原始图片存放路径\n",
    "OUTPUT_ROOT = \"C:/Users/Lenovo/Desktop/DC/request/2\"        # 处理结果根目录\n",
    "API_KEY = \"02e64499-e164-4871-b571-3788df88943c\"  # 大模型API密钥\n",
    "PROMPT = (\"你是一个专业的视觉识别大模型，需要比较两张输入灰度图片的差异。请依次分析以下几个维度的变化，并生成包含所有检测项的JSON文件：\\n场景主体：什么是该画面中的主体或新增/消失的人物\\n人物头部动作：检测人主体头部的姿势变化:\\n主体面部表情变化：识别主体面部表情的细微变化判断主体的情绪变化；\\n主体手部动作：分析主体手部动作的变化或者运动趋势；\\n主体腿部动作：分析主体腿部动作的变化或者运动趋势，分析其与主体身体运动的关系；\\n动植物：检测生物数量、种类、位置或形态变化（如植物生长、动物姿态）；\\n镜头角度：通过几何特征判断拍摄视角差异（画面向上或下移动/水平移动/焦距变化如镜头拉近或拉远）；\\n景深变化：检测场景镜头缩放变化，如镜头拉近或拉远等:\\n事物速度，请分析画面主体是否有向某一方向的动量或速度，\\n主体动作趋势：检测整个主体身体关键部位变化所导致的运动趋势如体准备向上跳起等:\\n输出规则：1.每个维度需独立分析，若未检测到变化则值为\\\"无变化\\\"2.动态变化需用动词短语描述（如\\\"人物从行走变为跳跃\\\"）3.静态变化需用名词短语+状态描述（如\\\"树木新增：右侧出现一棵高度约2米的松树\\\"）\\n示例输出：{\\\"主体\\\":\\\"几只鸟\\\",\\n\\\"人物头部动作\\\": \\\"左侧人物稍稍抬起头\\\",\\n\\\"主体面部表情变化\\\":\\\"主体表情从平静变为喜悦(嘴角上挑，眉毛上扬)\\\",\\n\\\"主体手部动作\\\": \\\"手臂耷拉在两旁(握紧双拳)\\\",\\n\\\"主体腿部动作\\\": \\\"双腿直立微曲\\\",\\n\\\"动植物\\\": \\\"花盆中新增3朵盛开白色花朵\\\",\\n\\\"镜头角度\\\": \\\"从仰视变为平视\\\",\\n\\\"景深\\\": \\\"人物变大，画面拉近\\\",\\n\\\"动量\\\":\\\"主体有向上移动的速度或趋势\\\"},\\n\\\"动作趋势\\\":\\\"主体准备向上跳起\\\"\")\n",
    "                         # 可自定义的提示语"
   ],
   "id": "2f54f7ba82ccee94",
   "outputs": [],
   "execution_count": 5
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-15T13:48:26.947504Z",
     "start_time": "2025-03-15T13:48:26.927806Z"
    }
   },
   "cell_type": "code",
   "source": [
    "def image_to_base64(img):\n",
    "    \"\"\"将PIL.Image对象转换为base64字符串（网页7实现）\"\"\"\n",
    "    buffered = BytesIO()\n",
    "    img.save(buffered, format=\"JPEG\")\n",
    "    return base64.b64encode(buffered.getvalue()).decode('utf-8')\n",
    "\n",
    "def process_and_analyze_images():\n",
    "    \"\"\"图片处理与大模型分析一体化流程\"\"\"\n",
    "    flag = 0\n",
    "    for subdir in os.listdir(INPUT_PATH):\n",
    "        time.sleep(0.5)\n",
    "        subdir_path = os.path.join(INPUT_PATH, subdir)\n",
    "        if not os.path.isdir(subdir_path):\n",
    "            continue\n",
    "\n",
    "        # 创建带时间戳的输出目录\n",
    "        timestamp = datetime.now().strftime(\"%Y%m%d%H%M%S\")\n",
    "        output_path = os.path.join(OUTPUT_ROOT, f\"{subdir}_{timestamp}\")\n",
    "        os.makedirs(output_path, exist_ok=True)\n",
    "\n",
    "        try:\n",
    "            # 阶段一：图片读取与处理\n",
    "            processed_images = []\n",
    "            image_data_list = []\n",
    "            \n",
    "            for idx, file in enumerate(sorted(os.listdir(subdir_path))[:2]):  # 仅处理前两张图\n",
    "                img_path = os.path.join(subdir_path, file)\n",
    "                with Image.open(img_path) as img:\n",
    "                    # 灰度转换与尺寸裁剪\n",
    "                    gray_img = img.convert('L')\n",
    "                    width, height = gray_img.size\n",
    "                    scale = max(512/width, 512/height)\n",
    "                    resized = gray_img.resize((int(width*scale), int(height*scale)), Image.LANCZOS)\n",
    "                    cropped = resized.crop((\n",
    "                        (resized.width-512)//2, \n",
    "                        (resized.height-512)//2,\n",
    "                        (resized.width+512)//2,\n",
    "                        (resized.height+512)//2\n",
    "                    ))\n",
    "                    \n",
    "                    # 保存处理后的图片到本地\n",
    "                    save_path = os.path.join(output_path, f\"processed_{idx}.jpg\")\n",
    "                    cropped.save(save_path)\n",
    "                    processed_images.append(save_path)\n",
    "                    \n",
    "                    # 转换为base64编码\n",
    "                    image_data_list.append(f\"data:image/jpeg;base64,{image_to_base64(cropped)}\")\n",
    "\n",
    "            # 阶段二：大模型调用\n",
    "            payload = {\n",
    "                \"model\": \"doubao-1-5-vision-pro-32k-250115\",\n",
    "                \"messages\": [{\n",
    "                    \"role\": \"user\",\n",
    "                    \"content\": [\n",
    "                        {\"type\": \"text\", \"text\": PROMPT},\n",
    "                        *[{\"type\": \"image_url\", \"image_url\": {\"url\": url}} \n",
    "                          for url in image_data_list]\n",
    "                    ]\n",
    "                }]\n",
    "            }\n",
    "            \n",
    "            response = requests.post(\n",
    "                \"https://ark.cn-beijing.volces.com/api/v3/chat/completions\",\n",
    "                headers={\"Authorization\": f\"Bearer {API_KEY}\", \"Content-Type\": \"application/json\"},\n",
    "                json=payload,\n",
    "                timeout=30\n",
    "            )\n",
    "            \n",
    "            # 保存分析结果\n",
    "            result_path = os.path.join(output_path, \"result.txt\")\n",
    "            with open(result_path, \"w\", encoding=\"utf-8\") as f:\n",
    "                if response.status_code == 200:\n",
    "                    result = response.json()['choices'][0]['message']['content']\n",
    "                    f.write(f\"{result}\")\n",
    "                else:\n",
    "                    f.write(f\"错误代码 {response.status_code}:\\n{response.text}\")\n",
    "                    flag = 1\n",
    "                    break\n",
    "            if flag:\n",
    "                break\n",
    "        except Exception as e:\n",
    "            error_log = os.path.join(output_path, \"error.log\")\n",
    "            with open(error_log, \"w\") as f:\n",
    "                f.write(f\"处理异常: {str(e)}\")"
   ],
   "id": "ee8b647f3a37929c",
   "outputs": [],
   "execution_count": 3
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-15T15:25:19.797246Z",
     "start_time": "2025-03-15T14:56:23.860235Z"
    }
   },
   "cell_type": "code",
   "source": [
    "if __name__ == \"__main__\":\n",
    "    process_and_analyze_images()\n",
    "    print(\"图片处理与分析流程执行完成，结果已保存至:\", OUTPUT_ROOT)"
   ],
   "id": "82d556ba378c03b8",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "图片处理与分析流程执行完成，结果已保存至: C:/Users/Lenovo/Desktop/DC/request/2\n"
     ]
    }
   ],
   "execution_count": 6
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": "",
   "id": "aeab7ad5620ee5a7"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
